import _ from 'lodash';

if (!String.prototype.padStart) {
  String.prototype.padStart = function padStart(targetLength, padString) {
    targetLength = targetLength >> 0; //truncate if number or convert non-number to 0;
    padString = String((typeof padString !== 'undefined' ? padString : ' '));
    if (this.length > targetLength) {
      return String(this);
    }
    else {
      targetLength = targetLength - this.length;
      if (targetLength > padString.length) {
        padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed
      }
      return padString.slice(0, targetLength) + String(this);
    }
  };
}

/****** StorageEnum 缓存枚举, LocalStorage & SessionStorage **************************************************************************/
export const StorageEnum = {
  LocalStorage: 'local',
  SessionStorage: 'session'
}

/**
 * 校验对象是为空对象: null, undefined, NaN
 * @param {Object} value 校验对象, 默认为 null
 * @param {Boolean} clearSpace 是否去掉不可见字符: value 为 string 类型时有效, 默认为 false
 * @returns true-空对象, false-非空对象
 */
export function isEmpty(value = null, clearSpace = false) {

  // 对常见的“非”值(不包含bool型)，直接返回原来值
  const empty = [null, undefined, NaN, ""]
  if (empty.includes(value)) return true

  // 清理空格、制表符后再校验
  if (typeof value === 'string' && clearSpace) {
    return 0 === value.replace(/\s+/g, '').length
  }

  return false
}

/**
 * 判断对象是否非空对象
 * 
 * @param {any} value
 * @param {any} clearSpace
 * @returns
 */
export function isNotEmpty(value = null, clearSpace = false) {
  return !isEmpty(value, clearSpace)
}

/**
 * 设置 Storage 缓存
 * @param {String} key 关键字
 * @param {String} value 值
 * @param {String} type 类型: local-localStorage, session-sessionStorage, 默认为 local
 */
export function setStorage(key = null, value = null, type = StorageEnum.LocalStorage) {
  if (isEmpty(key)) return
  if (typeof key !== 'string') return

  // 类型处理
  let dataType = typeof (value);
  if (value instanceof Date) {
    dataType = 'date';
  }

  // 固定格式存储
  const obj = JSON.stringify({
    dataType,
    content: value
  })

  const { LocalStorage, SessionStorage } = StorageEnum;
  switch (type) {
    case LocalStorage: localStorage.setItem(key, obj); break;
    case SessionStorage: sessionStorage.setItem(key, obj); break;
    default: break;
  }
}


/****** setSessionStorage 设置 SessionStorage 缓存 ***********************************************************************************/
/**
 * 设置 SessionStorage 缓存
 * @param {String} key 关键字
 * @param {String} value 值
 */
export function setSessionStorage(key = null, value = null) {
  setStorage(key, value, StorageEnum.SessionStorage);
}


/****** getStorage 获取 Storage 缓存 **************************************************************************************************/
/**
 * 获取 Storage 缓存
 * @param {String} key 
 * @param {String} type 
 */
export function getStorage(key = null, type = StorageEnum.LocalStorage) {
  if (isEmpty(key)) return
  if (typeof key !== 'string') return

  let _storage;
  if (type == StorageEnum.LocalStorage) {
    _storage = localStorage.getItem(key);
  } else if (type == StorageEnum.SessionStorage) {
    _storage = sessionStorage.getItem(key);
  }

  if (!isEmpty(_storage)) {
    _storage = JSON.parse(_storage);

    switch (_storage.dataType) {
      case 'number': _storage = _storage.content / 1; break;
      case 'string':
      case 'boolean':
      case 'object': _storage = _storage.content; break;
      case 'date': _storage = new Date(_storage.content); break;
      default: _storage = _storage.content;
    }
  }

  return _storage
}


/****** getSessionStorage 获取 SessionStorage 缓存 ***********************************************************************************/
/**
 * 获取 SessionStorage 缓存
 * @param {String} key 关键字
 */
export function getSessionStorage(key = null) {
  return getStorage(key, StorageEnum.SessionStorage);
}

/****** validStorage 校验 Storage 缓存是否存在 ****************************************************************************************/
/**
 * 校验 Storage 缓存是否存在
 * @param {String} key 关键字
 * @param {String} type 类型: local-localStorage, session-sessionStorage, 默认为 local
 * @returns true-存在, false-不存在
 */
export function validStorage(key = null, type = StorageEnum.LocalStorage) {
  if (isEmpty(key, true)) return false
  if (typeof key != 'string') return false
  const { LocalStorage, SessionStorage } = StorageEnum;

  let result = '';
  switch (type) {
    case LocalStorage:
      localStorage.getItem(key);
      break;
    case SessionStorage:
      sessionStorage.getItem(key);
      break;
    default:
      break;
  }

  return !isEmpty(result);
}

/****** removeStorage 根据 key 删除 Storage 缓存 *************************************************************************************/
/**
 * 根据 key 删除 Storage 缓存
 * @param {String} key 关键字
 * @param {String} type 类型: local-localStorage, session-sessionStorage, 默认为 local
 */
export function removeStorage(key = null, type = StorageEnum.LocalStorage) {
  if (isEmpty(key)) return
  if (typeof key !== 'string') return

  const { LocalStorage, SessionStorage } = StorageEnum;
  switch (type) {
    case LocalStorage:
      localStorage.removeItem(key);
      break;
    case SessionStorage:
      sessionStorage.removeItem(key);
      break;
    default:
      break;
  }
}


/****** clearStorage 清理 Storage 缓存 ***********************************************************************************************/
/**
 * 清理 Storage 缓存
 */
export function clearStorage() {
  localStorage.clear()
  sessionStorage.clear()
}



/**
 * 获取uuid
 * @returns {string} uuid
 */
export function getUuid() {
  return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    const r = Math.random() * 16 | 0;
    const v = c === 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  })
}

/**
 * 校验对象是为空对象: null, undefined, NaN
 * @param value 校验对象 []
 * @param clearSpace 是否去掉不可见字符: value 为 string 类型时有效, 默认为 false
 * @returns true-空对象, false-非空对象
 */
export function isEmptys(values, clearSpace = false) {
  if (values instanceof Array) {
    return !values.length || values.some(value => isEmpty(value, clearSpace))
  }
  return true
}


/**
* 校验对象或数组是否为空: {} [] 字符串类型
* @param obj
* @returns {boolean}
*/
export const isEmptyObj = obj => [null, undefined].includes(obj) ? true : Object.keys(obj).length === 0

/**
 * 校验对象是否未非空对象
 * @param obj
 * @returns {boolean}
 */
export function isNotEmptyObj(obj) {
  return !isEmptyObj(obj)
}

/**
 * 金额分段格式化
 * @param {number} money 
 * @param {bit} bit 
 */
export function moneyFormat(money = 0, bit = 3) {
  if (isEmptys([money, bit])) return money;
  return money.toString().replace(new RegExp(`\\B(?=(\\d{${bit}})+(?!\\d))`, 'g'), ",");
}

/**
 * 数组转树
 * @param {Array|String} array 需要转化的数组
 * @param {String} key 关键字字段名
 * @param {String} parentKey 父级编号字段
 * @param {String} childrenKey 孩子节点字段
 * @returns {Array} 树
 */
export function arrayToTree(array = [], key = 'id', parentKey = 'parentId', childrenKey = 'children') {
  if (isEmpty(array)) return []
  // 默认参数
  let _default = {
    data: [],
    key: "id",
    parentKey: 'parentId',
    childrenKey: 'children'
  }
  let result = []

  // 如果是字符串，先转换为对象再校验格式
  if (typeof array === 'string') {
    try {
      let _arr = JSON.parse(array);
      if (_arr instanceof Array) {
        // 反序列化后如果是数组，则继续
        _default.data = _arr;
      } else {
        // 不是数组，则格式错误
        console.log('数据格式错误', _arr);
        return _default.data;
      }
    } catch (e) {
      // 反序列化失败, 说明数据格式有误
      console.log('数据格式错误', e);
      return _default.data;
    }
  } else if (array instanceof Array) {
    // 如果是数组，直接克隆
    _default.data = JSON.parse(JSON.stringify(array));
  } else {
    // 其他数据格式，不满足要求
    console.log('数据格式错误');
    return _default.data;
  }

  if (!isEmpty(key)) _default.key = key;
  if (!isEmpty(parentKey)) _default.parentKey = parentKey;
  if (!isEmpty(childrenKey)) _default.childrenKey = childrenKey;
  if (array.length) {
    let allIdMap = {};

    array.forEach(item => {
      const _id = item[_default.key];
      if (!isEmpty(_id)) allIdMap[_id] = item;
    })

    array.forEach(item => {
      const _pid = item[_default.parentKey];

      if (!isEmpty(_pid)) {
        const parent = allIdMap[_pid];
        if (parent) {
          // 如果存在父级节点，将当前节点添加到父级节点的孩子节点集合
          if (isEmpty(parent[_default.childrenKey])) parent[_default.childrenKey] = [];
          parent[_default.childrenKey].push(item);
        } else {
          // 顶级节点，这里的item是引用对象
          result.push(item);
        }
      }
    })
  }

  return result;
}

/** 打乱数组 */
export function randomArray(array = []) {
  try {
    // 原理是sort排序,Math.random()产生0<= x < 1之间的数,会导致x-0.05大于或者小于0
    return array.sort(() => Math.random() - 0.5);
  } catch (e) {
    console.error(e);
  }
}

/**
* 返回一个范围之间的随机数
* @param {Number} min
* @param {Number} max
*/
export function random(min, max) {
  if (min >= 0 && max > 0 && max >= min) {
    let gab = max - min + 1;
    return Math.floor(Math.random() * gab + min);
  } else {
    return 0;
  }
}


export function PageData(data) {
  const list = _.get(data, 'tables[0].table', [])
  const totle = _.get(data, 'tables[1].table[0].Total', 0)
  return {
    list,
    totle
  }
}

export function formatRequestData(data) {
  if (!data) return;
  for (let key in data) {
    if (isEmpty(data[key])) {
      data[key] = '';
    }
  }
}
